package com.ingenio.dao;


import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.ingenio.Adapter;
import com.ingenio.business.Almacen;
import com.ingenio.business.DetalleRecuento;
import com.ingenio.business.EstadoRecuento;
import com.ingenio.business.Recuento;
import com.ingenio.business.Usuario;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import com.mysql.jdbc.Statement;

public class RecuentoAdapter extends Adapter{
	
	public Recuento devolverRecuento(Integer idRec) throws Exception{
    	Connection conn = null;
    	Recuento r = null, recAnt = null;
    	RecuentoAdapter ra = new RecuentoAdapter();
    	PreparedStatement stmt = null;
    	EstadoRecuento er = null;
		UsuarioAdapter ua = new UsuarioAdapter();
		Usuario usuPlan = null, usuRec = null;
    	try {
    		conn = (Connection) abrirConexion();
    		String sel ="SELECT * FROM recuento WHERE IdRecuento = ?";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setInt(1, idRec);
    		ResultSet result = stmt.executeQuery();
    		
    		if(result.next()){
    			Date fechaPlanRecuento = result.getTimestamp("fechaPlanRecuento");
    			Integer idUsuPlan = result.getInt("IdUsuPlanificador");
    			Integer idUsuRec = result.getInt("IdUsuRecuento");
    			boolean bloqueaStock = result.getBoolean("bloqueaStock");
    			Integer idRecAnterior = result.getInt("IdRecuentoAnterior");
    			usuPlan = ua.devolverUsuario(idUsuPlan);
    			usuRec = ua.devolverUsuario(idUsuRec);
    			recAnt = ra.devolverRecuento(idRecAnterior);
    			r = new Recuento(idRec, fechaPlanRecuento, bloqueaStock, usuPlan, usuRec, recAnt, er);
    		}
    	}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
		return r;
    }
	
	public List<Recuento> devolverRecuentosBloqueanStock() throws Exception{
    	Connection conn = null;
    	Recuento r = null;
    	PreparedStatement stmt = null;
    	EstadoRecuentoAdapter era = new EstadoRecuentoAdapter();
    	EstadoRecuento er = era.devolverEstadoRecuento(2);
		UsuarioAdapter ua = new UsuarioAdapter();
		Usuario usuPlan = null, usuRec = null;
		List<Recuento> recuentosBloqueanStok = new ArrayList<Recuento>();
    	try {
    		conn = (Connection) abrirConexion();
    		String sel ="SELECT * FROM recuento WHERE bloqueaStock = 1 and IdEstadoRecuento = ?";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setInt(1, 2); // Estado del pedido 2: Pendiente
    		ResultSet result = stmt.executeQuery();
    		while(result.next()){
    			Integer idRec = result.getInt("IdRecuento"); 
    			Date fechaPlanRecuento = result.getTimestamp("fechaPlanRecuento");
    			Integer idUsuPlan = result.getInt("IdUsuPlanificador");
    			Integer idUsuRec = result.getInt("IdUsuRecuento");
    			boolean bloqueaStock = result.getBoolean("bloqueaStock");
    			usuPlan = ua.devolverUsuario(idUsuPlan);
    			usuRec = ua.devolverUsuario(idUsuRec);
    			r = new Recuento(idRec, fechaPlanRecuento, bloqueaStock, usuPlan, usuRec, null, er);
    			recuentosBloqueanStok.add(r);
    		}
    	}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
		return recuentosBloqueanStok;
    }
	
	public List<Recuento> devolverRecuentosPendientes(Usuario usuEncargado) throws Exception{
    	Connection conn = null;
    	Recuento r = null;
    	PreparedStatement stmt = null;
    	EstadoRecuentoAdapter era = new EstadoRecuentoAdapter();
    	EstadoRecuento er = era.devolverEstadoRecuento(2);
		UsuarioAdapter ua = new UsuarioAdapter();
		Usuario usuPlan = null;
		List<Recuento> recunetosPendientes = new ArrayList<Recuento>();
    	try {
    		conn = (Connection) abrirConexion();
    		String sel ="SELECT * FROM recuento WHERE IdEstadoRecuento = ? AND IdUsuRecuento = ?";
    		stmt = (PreparedStatement) conn.prepareStatement(sel);
    		stmt.setInt(1, 2); // Estado del pedido 2: Pendiente
    		stmt.setInt(2, usuEncargado.getIdUsuario());
    		ResultSet result = stmt.executeQuery();
    		while(result.next()){
    			Integer idRec = result.getInt("IdRecuento"); 
    			Date fechaPlanRecuento = result.getTimestamp("fechaPlanRecuento");
    			Integer idUsuPlan = result.getInt("IdUsuPlanificador");
    			boolean bloqueaStock = result.getBoolean("bloqueaStock");
    			usuPlan = ua.devolverUsuario(idUsuPlan);
    			r = new Recuento(idRec, fechaPlanRecuento, bloqueaStock, usuPlan, usuEncargado, null, er);
    			recunetosPendientes.add(r);
    		}
    	}
    	catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
		return recunetosPendientes;
    }
	
	public Almacen devolverAlmacen(Recuento r) throws Exception{
		Connection conn = null;
		Almacen a = null;
		AlmacenAdapter aa = new AlmacenAdapter();
		PreparedStatement stmt = null;
		try{
			conn = (Connection) abrirConexion();
			String sel ="SELECT IdAlmacen FROM detallerecuento WHERE IdRecuento=? LIMIT 1";
			stmt = (PreparedStatement) conn.prepareStatement(sel);
			stmt.setInt(1, r.getIdRecuento());
			ResultSet result = stmt.executeQuery();
			if(result.next()){
				Integer idAlmacen = result.getInt("IdAlmacen");
				a = aa.devolverAlmacen(idAlmacen);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
		finally{
			cerrarConexion(conn);
		}
		return a;
	}
	
	public void agregarRecuento(Recuento recuento) throws Exception{
		Connection conn = null;
		PreparedStatement stmt = null;
		DetalleRecuentoAdapter dra = new DetalleRecuentoAdapter();
		try {
			conn = (Connection) abrirConexion();
	    	conn.setAutoCommit(false);
	    	String add ="INSERT into recuento (fechaPlanRecuento, IdUsuPlanificador, IdUsuRecuento, bloqueaStock, IdRecuentoAnterior,IdEstadoRecuento) " +
					"VALUES (?, ?, ?, ?, ?,2)";
			stmt = (PreparedStatement) conn.prepareStatement(add, Statement.RETURN_GENERATED_KEYS);
			stmt.setTimestamp(1, new Timestamp(recuento.getFechaRecuento().getTime()));
//			stmt.setInt(2, recuento.getUsuarioPlan().getIdUsuario());
			//Hardcodeamos el usuario "logueado" 
			stmt.setInt(2, 1);
			stmt.setInt(3, recuento.getUsuarioRec().getIdUsuario());
			stmt.setBoolean(4, recuento.isBloqueaStock());
			stmt.setInt(5, (recuento.getRecuentoAnterior()!=null)?recuento.getRecuentoAnterior().getIdRecuento():0);
			stmt.executeUpdate();
			ResultSet generatedKeys = (ResultSet) stmt.getGeneratedKeys();
			
			if(generatedKeys.next()){
				Integer idNewRecuento = generatedKeys.getInt(1);
				List<DetalleRecuento> detalles = recuento.getDetallesRecuento();
				boolean guardo = dra.guardarDetalleRecuento(detalles, idNewRecuento,conn);
				if(guardo){
					conn.commit();
				}else{
					conn.rollback();
					throw new Exception("Error al tratar de guardar detalle de recuento");
				}
			}
		}
    	catch (Exception e) {
			conn.rollback();
    		e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}

	public void registrarRecuento(Recuento recuento) throws Exception{
		Connection conn = null;
		DetalleRecuentoAdapter dra = new DetalleRecuentoAdapter();
		PreparedStatement stmt = null;
    	boolean execute = false;
    	
    	// pregunto si el recuento esta cerrado 
    	//boolean cerrado = recuento.recuentoCerraro();
    	
    	try {
    		conn = (Connection) abrirConexion();
    		conn.setAutoCommit(false);
    		execute = dra.registrarDetalleRecuento(recuento.getDetallesRecuento(), conn);
    		if (execute){
    			String query = "UPDATE recuento SET IdEstadoRecuento = ? WHERE IdRecuento = ?";
    			stmt = (PreparedStatement) conn.prepareStatement(query);
    			stmt.setInt(1, 1); // seteo estado --> 1.- Cerrado
    			stmt.setInt(2, recuento.getIdRecuento());
    			stmt.executeUpdate();
    			conn.commit();
    		}else{
				conn.rollback();
				throw new Exception("Error al tratar de Registrar Recuento");
			}
    	}
    	catch(Exception e) {
    		conn.rollback();
    		e.printStackTrace();
			throw new Exception("Error al conectar con la base de datos.", e);
		}
    	finally{
    		cerrarConexion(conn);
    	}
	}
	
}
